﻿using System;
using System.Collections.Generic;

using Dynamic.Core.Types;
using System.CodeDom.Compiler;
using System.CodeDom;
using Dynamic.Core.Attributes;
using System.Reflection;
using System.IO;

namespace Dynamic.Core.Generation
{
    /// <summary>
    /// 枚举生成器
    /// </summary>
    public class EnumsGenerator : GeneratorBase,IGenerator
    {
        //CodeCompileUnit targetUnit;
        //CodeNamespace namespaces;

        //public EnumsGenerator()
        //{
        //    targetUnit = new CodeCompileUnit();
        //    namespaces = new CodeNamespace("Valink.MasterData.Dictionaries.Enums");
        //    namespaces.Imports.Add(new CodeNamespaceImport("System"));
        //    targetUnit.Namespaces.Add(namespaces);
        //}

        //public void InitEnum()
        //{
        //    //List<XML_DICTIONARY_ENUMTYPEEntity> reval = RemotingManager<MasterDataDBLink>.GenericBusinessObject.SelectEntities<XML_DICTIONARY_ENUMTYPEEntity>(new WhereItemCollection(), new OrderItemCollection());

        //    //foreach (XML_DICTIONARY_ENUMTYPEEntity item in reval)
        //    //{
        //    //    CodeTypeDeclaration targetEnum = GetEnumTypeDeclaration(item);

        //    //    namespaces.Types.Add(targetEnum);
        //    //}
        //}

        //public CodeTypeDeclaration GetEnumTypeDeclaration(XML_DICTIONARY_ENUMTYPEEntity enumType)
        //{
        //    CodeTypeDeclaration targetEnum = new CodeTypeDeclaration(enumType.Name);
        //    targetEnum.IsEnum = true;
        //    targetEnum.TypeAttributes = TypeAttributes.Public;
        //    targetEnum.Members.AddRange(GetEnumValues(enumType));

        //    CodeAttributeDeclaration codeAtt = new CodeAttributeDeclaration(new CodeTypeReference(typeof(EnumTypeAttribute)), GetEnumTypeAttributeArguments(enumType));

        //    if (enumType.EnumType != null && enumType.EnumType.Value == (int)EnumsType.Flags)
        //    {
        //        targetEnum.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(FlagsAttribute))));
        //    }
        //    targetEnum.CustomAttributes.Add(codeAtt);
        //    targetEnum.Comments.AddRange(GetEnumTypeComments(enumType));

        //    return targetEnum;
        //}

        //public CodeCommentStatement[] GetEnumTypeComments(XML_DICTIONARY_ENUMTYPEEntity enumType)
        //{
        //    List<CodeCommentStatement> comms = new List<CodeCommentStatement>();
        //    string strComment = enumType.DisplayName;
        //    if (enumType.Memo != null && enumType.Memo.Length > 0 && string.Compare(strComment, enumType.Memo, true) != 0)
        //    {
        //        strComment += ":" + enumType.Memo;
        //    }

        //    comms.Add(new CodeCommentStatement("<summary>", true));
        //    comms.Add(new CodeCommentStatement(strComment, true));
        //    comms.Add(new CodeCommentStatement("</summary>", true));

        //    return comms.ToArray();
        //}

        //public CodeAttributeArgument[] GetEnumTypeAttributeArguments(XML_DICTIONARY_ENUMTYPEEntity enumType)
        //{
        //    List<CodeAttributeArgument> args = new List<CodeAttributeArgument>();

        //    //if (enumType.ID != null)
        //    //{
        //    //    CodeAttributeArgument id = new CodeAttributeArgument();
        //    //    id.Name = XML_DICTIONARY_ENUMTYPEEntity.SchemaEntity.ID;
        //    //    id.Value = new CodePrimitiveExpression(enumType.ID.Value.ToString());
        //    //    args.Add(id);
        //    //}

        //    //CodeAttributeArgument name = new CodeAttributeArgument();
        //    //name.Name = XML_DICTIONARY_ENUMTYPEEntity.SchemaEntity.Name;
        //    //name.Value = new CodePrimitiveExpression(enumType.Name);
        //    //args.Add(name);

        //    //CodeAttributeArgument displayName = new CodeAttributeArgument();
        //    //displayName.Name = XML_DICTIONARY_ENUMTYPEEntity.SchemaEntity.DisplayName;
        //    //displayName.Value = new CodePrimitiveExpression(enumType.DisplayName);
        //    //args.Add(displayName);

        //    //if (enumType.EnumType != null)
        //    //{
        //    //    CodeAttributeArgument type = new CodeAttributeArgument();
        //    //    type.Name = XML_DICTIONARY_ENUMTYPEEntity.SchemaEntity.EnumType;
        //    //    type.Value = new CodePrimitiveExpression(enumType.EnumType.Value);
        //    //    args.Add(type);
        //    //}

        //    //if (enumType.ParentID != null)
        //    //{
        //    //    CodeAttributeArgument parent = new CodeAttributeArgument();
        //    //    parent.Name = XML_DICTIONARY_ENUMTYPEEntity.SchemaEntity.ParentID;
        //    //    parent.Value = new CodePrimitiveExpression(enumType.ParentID.Value.ToString());
        //    //    args.Add(parent);
        //    //}

        //    return args.ToArray();
        //}

        //public CodeMemberField[] GetEnumValues(XML_DICTIONARY_ENUMTYPEEntity enumType)
        //{
        //    List<CodeMemberField> coll = new List<CodeMemberField>();
        //    //WhereItemCollection wic = new WhereItemCollection();
        //    //OrderItemCollection oic = new OrderItemCollection();
        //    //wic.Add(XML_DICTIONARY_ENUMVALUEEntity.RefEntity.GetEnumIDItem().ToWhereItem(enumType.ID));
        //    //oic.Add(XML_DICTIONARY_ENUMVALUEEntity.RefEntity.GetOrderNumItem().ToOrderItem());

        //    //List<XML_DICTIONARY_ENUMVALUEEntity> values = RemotingManager<MasterDataDBLink>.GenericBusinessObject.SelectEntities<XML_DICTIONARY_ENUMVALUEEntity>(wic, oic);

        //    //foreach (XML_DICTIONARY_ENUMVALUEEntity item in values)
        //    //{
        //    //    CodeMemberField tmp = new CodeMemberField();
        //    //    tmp.Name = item.Name;
        //    //    tmp.InitExpression = new CodePrimitiveExpression(item.Value);
        //    //    tmp.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(EnumValueAttribute)), GetEnumValueAttributeArguments(item)));

        //    //    tmp.Comments.AddRange(GetEnumValueComments(item));
        //    //    coll.Add(tmp);
        //    //}

        //    return coll.ToArray();
        //}

        //public CodeCommentStatement[] GetEnumValueComments(XML_DICTIONARY_ENUMVALUEEntity enumValue)
        //{
        //    List<CodeCommentStatement> comms = new List<CodeCommentStatement>();
        //    string strComment = enumValue.DisplayName;
        //    if (enumValue.Memo != null && enumValue.Memo.Length > 0 && string.Compare(strComment, enumValue.Memo, true) != 0)
        //    {
        //        strComment += ":" + enumValue.Memo;
        //    }

        //    comms.Add(new CodeCommentStatement("<summary>", true));
        //    comms.Add(new CodeCommentStatement(strComment, true));
        //    comms.Add(new CodeCommentStatement("</summary>", true));

        //    return comms.ToArray();
        //}

        //public CodeAttributeArgument[] GetEnumValueAttributeArguments(XML_DICTIONARY_ENUMVALUEEntity enumValue)
        //{
        //    List<CodeAttributeArgument> args = new List<CodeAttributeArgument>();

        //    //if (enumValue.ID != null)
        //    //{
        //    //    CodeAttributeArgument id = new CodeAttributeArgument();
        //    //    id.Name = XML_DICTIONARY_ENUMVALUEEntity.SchemaEntity.ID;
        //    //    id.Value = new CodePrimitiveExpression(enumValue.ID.Value.ToString());
        //    //    args.Add(id);
        //    //}

        //    //CodeAttributeArgument name = new CodeAttributeArgument();
        //    //name.Name = XML_DICTIONARY_ENUMVALUEEntity.SchemaEntity.Name;
        //    //name.Value = new CodePrimitiveExpression(enumValue.Name);
        //    //args.Add(name);

        //    //CodeAttributeArgument displayName = new CodeAttributeArgument();
        //    //displayName.Name = XML_DICTIONARY_ENUMVALUEEntity.SchemaEntity.DisplayName;
        //    //displayName.Value = new CodePrimitiveExpression(enumValue.DisplayName);
        //    //args.Add(displayName);

        //    //if (enumValue.EnumID != null)
        //    //{
        //    //    CodeAttributeArgument enumID = new CodeAttributeArgument();
        //    //    enumID.Name = XML_DICTIONARY_ENUMVALUEEntity.SchemaEntity.EnumID;
        //    //    enumID.Value = new CodePrimitiveExpression(enumValue.EnumID.Value.ToString());
        //    //    args.Add(enumID);
        //    //}

        //    //if (enumValue.OrderNum != null)
        //    //{
        //    //    CodeAttributeArgument orderNum = new CodeAttributeArgument();
        //    //    orderNum.Name = XML_DICTIONARY_ENUMVALUEEntity.SchemaEntity.OrderNum;
        //    //    orderNum.Value = new CodePrimitiveExpression(enumValue.OrderNum.Value);

        //    //    args.Add(orderNum);
        //    //}

        //    //if (enumValue.IsDefault != null)
        //    //{
        //    //    CodeAttributeArgument isDefault = new CodeAttributeArgument();
        //    //    isDefault.Name = XML_DICTIONARY_ENUMVALUEEntity.SchemaEntity.IsDefault;
        //    //    isDefault.Value = new CodePrimitiveExpression(enumValue.IsDefault.Value);

        //    //    args.Add(isDefault);
        //    //}

        //    return args.ToArray();
        //}


        //public void GenerateCSharpCode(string fileName)
        //{
        //    InitEnum();
        //    CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
        //    CodeGeneratorOptions options = new CodeGeneratorOptions();
        //    options.BracingStyle = "C";
        //    using (StreamWriter sourceWriter = new StreamWriter(fileName))
        //    {
        //        provider.GenerateCodeFromCompileUnit(
        //            targetUnit, sourceWriter, options);
        //    }
        //}

        //public bool CompileCSharpCode(String dllFile)
        //{
        //    GenerateCSharpCode(dllFile.Replace("dll", "cs"));
        //    CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
        //    CompilerParameters options = new CompilerParameters();
        //    options.GenerateExecutable = false;
        //    options.OutputAssembly = dllFile;
        //    options.GenerateInMemory = false;
        //    options.CompilerOptions = "/doc:" + dllFile.Replace("dll", "xml");
        //    options.ReferencedAssemblies.Add("Valink.MasterData.Dictionaries.dll");
        //    CompilerResults cr = provider.CompileAssemblyFromDom(options, new CodeCompileUnit[1] { targetUnit });

        //    if (cr.Errors.Count > 0)
        //    {
        //        Console.WriteLine("Errors building into {0}", cr.PathToAssembly);
        //        foreach (CompilerError ce in cr.Errors)
        //        {
        //            Console.WriteLine("{0}", ce.ToString());
        //            Console.WriteLine();
        //        }
        //    }
        //    else
        //    {
        //        Console.WriteLine("Source built into {0} successfully.", cr.PathToAssembly);
        //    }

        //    if (cr.Errors.Count > 0)
        //    {
        //        return false;
        //    }
        //    else
        //    {
        //        return true;
        //    }
        //}       

        /// <summary>
        /// 
        /// </summary>
        /// <param name="savePath"></param>
        /// <param name="generateType"></param>
        /// <param name="langrageType"></param>
        /// <param name="schema"></param>
        /// <param name="exclude"></param>
        public override void Generator(string savePath, GenerateType generateType, GenerateLanguageType langrageType, string schema, List<string> exclude)
        {
            throw new NotImplementedException();
        }
    }
}
